using System;
using dnAnalytics.LinearAlgebra;
using dnAnalytics.LinearAlgebra.Solvers;

namespace dnAnalytics.Examples.LinearAlgebra.Solvers
{
    /// <summary>
    /// Provides an example of the creation of the convergence monitor
    /// </summary>
    public sealed class ConvergenceMonitorShouldCalculationContinue
    {
        /// <summary>
        /// Creates a convergence monitor.
        /// </summary>
        public void UseMonitor()
        {
            // Set the maximum number of iterations that the convergence monitor
            // will allow before indicating that the iteration must be stopped.
            int maximumNumberOfIterations = 10;

            // Set the value the residual must maximally have before the 
            // convergence monitor will declare that the iteration has converged.
            // Note that this residual is relative to the starting point which is
            // determined by the matrix norm.
            double minimumResidual = 1E-5;

            // Set the matrix norm. This will be used by the convergence monitor
            // to get a base line for the convergence limit.
            double matrixNorm = 10;

            // Finally create the convergence monitor with the values
            // we have defined above
            ConvergenceMonitor monitor = new ConvergenceMonitor(maximumNumberOfIterations,
                                                                minimumResidual,
                                                                matrixNorm);
            
            // To be able to use the convergence monitor we'll need a solution vector and
            // a residual vector. For now fill both with silly numbers.
            Vector solutionVector = VectorBuilder.CreateVector(10, 2.5, VectorType.Dense);
            Vector residualVector = VectorBuilder.CreateVector(10, 1.5, VectorType.Dense);

            // Now use the monitor in a fake iteration. If all goes well this iteration should
            // stop because the number of iterations becomes larger than the number of iterations
            // we allow.
            int currentIteration = 0;
            while (monitor.ShouldCalculationContinue(currentIteration,solutionVector,residualVector))
            {
                Console.WriteLine("Working. Iteration no: " + currentIteration.ToString());
                currentIteration++;
            }
            
            // Indicate that we exited the loop
            Console.WriteLine("Stopped working.");
            // Indicate why we exited the loop. Note that this should say
            // SolutionStatus.IterationBoundsReached.
            Console.WriteLine("Stop reason: " + monitor.SolutionStatus.ToString());
        }
    }
}